package com.sihai.ehr.service.impl;

import java.text.MessageFormat;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.stereotype.Service;

import com.sihai.core.DataAccessor;
import com.sihai.core.DynamicQuery;
import com.sihai.core.Limit;
import com.sihai.core.LimitedList;
import com.sihai.core.QueryCreator;
import com.sihai.core.Sorter;
import com.sihai.ehr.model.biz.InviteApply;
import com.sihai.ehr.model.biz.InviteApplyAuditing;
import com.sihai.ehr.model.biz.TrainOutingPlanCloseAuditing;
import com.sihai.ehr.model.biz.TrainPlan;
import com.sihai.ehr.model.biz.TrainPlanAuditing;
import com.sihai.ehr.model.biz.TrainRealiaResource;
import com.sihai.ehr.model.sys.AuditStatus;
import com.sihai.ehr.repository.AuditingRepository;
import com.sihai.ehr.service.TrainPlanService;

/**
 * 培训计划服务实现
 * 
 * @author henry
 * 
 */
@Service("trainPlanService")
public class TrainPlanServiceImpl implements TrainPlanService {
	@Resource
	DataAccessor dataAccessor;

	@Resource
	private AuditingRepository auditingRepository;

	@Override
	public TrainPlan getTrainPlan(Long id) {
		if (id == null || id < 0) {
			throw new RuntimeException("【传入参数非法】");
		}
		try {
			return dataAccessor.get(TrainPlan.class, id);
		} catch (Exception e) {
			throw new RuntimeException("【异常原因：获取培训计划明细数据库发生异常】【异常说明：+" + e.getMessage() + "】【发生地点：TrainPlanServiceImpl.getTrainPlan;参数id=" + id + " 】");
		}
	}

	@Override
	public LimitedList<TrainPlan> getTrainPlans(final Long organizationId, Long dutyId, final int lecturerType,final AuditStatus auditStatus, Limit limit, Sorter sorter) {
		if (organizationId == null || organizationId < 0) {
			throw new RuntimeException("【传入参数非法】");
		}
		try {
			return dataAccessor.findByQuery(TrainPlan.class, new QueryCreator() {

				@Override
				public Query createQuery(Session session) {
					DynamicQuery dynamicQuery = new DynamicQuery("from TrainPlan t where t.status=0");
					dynamicQuery.append(" and t.organization.treePath like '%," + organizationId + ",%'");
					if (lecturerType > -1) {
						dynamicQuery.append("and t.lecturerType=" + lecturerType);
					}
					if(auditStatus != null){
						dynamicQuery.append("and t.auditStatus=" + auditStatus.ordinal());
					}
					return dynamicQuery.build(session);
				}
			}, limit, sorter);
		} catch (Exception e) {
			throw new RuntimeException("【异常原因：获取培训计划时数据库发生异常】【异常说明：+" + e.getMessage() + "】【发生地点：TrainPlanServiceImpl.getTrainPlans;参数organizationId=" + organizationId + "】");
		}
	}

	@Override
	public LimitedList<TrainPlan> getTrainPlans(final int year, final int lecturerType, final String category, final Long lecturerWorkId, Limit limit, Sorter sorter) {
		try {
			return dataAccessor.findByQuery(TrainPlan.class, new QueryCreator() {

				@Override
				public Query createQuery(Session session) {
					DynamicQuery dynamicQuery = new DynamicQuery("from TrainPlan t where t.status=0");

					if (lecturerType > -1) {
						dynamicQuery.append(" and t.lecturerType=" + lecturerType);
					}

					if (year > -1) {
						dynamicQuery.append(" and t.planStartDate between date_format('"
								+ year
								+ "-01-01 00:01','%Y-%c-%d %H:%i:%s')"
								+ " and date_format('"
								+ year
								+ "-12-31 23:59','%Y-%c-%d %H:%i:%s')");
					}

					if (category != null && category.length() > 0) {
						dynamicQuery.append(" and t.category='" + category + "'");
					}

					if (lecturerWorkId > -1) {
						dynamicQuery.append(" and t.trainLecturer.employeeinfoWork.id=" + lecturerWorkId);
					}
					return dynamicQuery.build(session);
				}
			}, limit, sorter);
		} catch (Exception e) {
			throw new RuntimeException("【异常原因：获取培训计划时数据库发生异常】【异常说明：+" + e.getMessage() + "】【发生地点：TrainPlanServiceImpl.getTrainPlans;参数year,lecturertype,etc.】");
		}
	}

	@Override
	public LimitedList<TrainPlan> getTrainPlansByUserId(final Long organizationId, Long dutyId, final Long userId, Limit limit, Sorter sorter) {
		if (organizationId == null || organizationId < 0) {
			throw new RuntimeException("【传入参数非法】");
		}
		try {
			return dataAccessor.findByQuery(TrainPlan.class, new QueryCreator() {

				@Override
				public Query createQuery(Session session) {
					DynamicQuery dynamicQuery = new DynamicQuery("from TrainPlan t where t.status=0 ");
					dynamicQuery.append(" and t.organization.treePath like '%," + organizationId + ",%'");
					dynamicQuery.append(" and (t.id in (select d.trainPlan.id from TrainPlanDutyTarget d "
							+ "where d.duty.id=(select e.duty.id from EmployeeinfoWork e where e.baseId.id=" + userId + "))"
							+ " or t.id in (select p.trainPlan.id from TrainPlanEmployeeTarget p where p.employeeinfoWork.baseId.id=" + userId + ")" + ")");

					return dynamicQuery.build(session);
				}
			}, limit, sorter);
		} catch (Exception e) {
			throw new RuntimeException("【异常原因：获取培训计划时数据库发生异常】【异常说明：+" + e.getMessage() + "】【发生地点：TrainPlanServiceImpl.getTrainPlans;参数organizationId=" + organizationId + "】");
		}
	}
	
	@Override
	public LimitedList<TrainPlan> getTrainPlansByWorkId(final Long workId,
			Limit limit, Sorter sorter) {
		try {
			return dataAccessor.findByQuery(TrainPlan.class, new QueryCreator() {

				@Override
				public Query createQuery(Session session) {
					DynamicQuery dynamicQuery = new DynamicQuery("from TrainPlan t where t.status=0 ");
					dynamicQuery.append(" and (t.id in (select d.trainPlan.id from TrainPlanDutyTarget d "
							+ "where d.duty.id=(select e.duty.id from EmployeeinfoWork e where e.id=" + workId + "))"
							+ " or t.id in (select p.trainPlan.id from TrainPlanEmployeeTarget p where p.employeeinfoWork.id=" + workId + ")" + ")");

					return dynamicQuery.build(session);
				}
			}, limit, sorter);
		} catch (Exception e) {
			throw new RuntimeException("【异常原因：获取培训计划时数据库发生异常】【异常说明：+" + e.getMessage() + "】【发生地点：TrainPlanServiceImpl.getTrainPlansByWorkId;参数workId=" + workId + "】");
		}
	}

	@Override
	public void save(TrainPlan trainPlan) {
		if (trainPlan == null || trainPlan.getOrganization() == null) {
			throw new RuntimeException("【trainPlan对象参数异常】");
		}
		boolean isNew = trainPlan.getId() != null && trainPlan.getId() > 0 ? false : true;
		try {
			dataAccessor.saveOrUpdate(trainPlan);
			if (isNew) {
				saveTrainPlanAuditingProcess(trainPlan, 1);
			}
		} catch (Exception e) {
			throw new RuntimeException("【异常原因：保培训计划对象到数据库发生异常】【异常说明：" + e.getMessage() + "】【发生地点：TrainPlanServiceImpl.save】");
		}
	}

	@Override
	public void deleteTrainPlan(final String ids) {
		if (ids == null || ids.isEmpty()) {
			throw new RuntimeException("【参数异常：ids为空】");
		}
		try {
			//删除审核信息
			//deleteTrainPlanAuditings(ids);
			//删除培训计划
			dataAccessor.batchUpdate(new QueryCreator() {
				@Override
				public Query createQuery(Session session) {
					return session.createQuery(MessageFormat
							.format("update TrainPlan t set t.status = 1 where t.id in ({0})",
									ids));
				}
			});
		} catch (Exception e) {
			throw new RuntimeException("【异常原因：移出培训计划信息数据库发生异常】【异常说明：" + e.getMessage() + "】【发生地点：TrainPlanServiceImpl.deleteTrainPlan】");
		}
	}

	/**
	 * 创建审核流程
	 * 
	 * @param inviteApply
	 * @param auditNo
	 */
	@Override
	public void saveTrainPlanAuditingProcess(TrainPlan trainPlan, int auditNo) {
		try {
			auditingRepository.saveAuditingProcess(trainPlan, auditNo);
		} catch (Exception ex) {
			//
		}
	}
	@Override
	public void saveTrainPlanCloseAuditingProcess(TrainPlan trainPlan, int auditNo) {
		try {
			auditingRepository.saveTrainOutingPlanCloseAduitingProcess(trainPlan, auditNo);
		} catch (Exception ex) {
			//
		}
	}
	
	// 创建审核流程
	private void deleteTrainPlanAuditings(String ids) {
		auditingRepository.deleteAuditingProcess(new TrainPlan(),ids);
	}

	@Override
	public List<List<TrainPlanAuditing>> searchTrainPlanAuditings(Long trainPlanId, Limit limit, Sorter sorter) {
		return auditingRepository.findByHql(TrainPlanAuditing.class, "from TrainPlanAuditing i where i.trainPlan.id = ?", new Object[] { trainPlanId });
	}
	
	@Override
	public List<List<TrainOutingPlanCloseAuditing>> searchTrainPlanCloseAuditings(Long trainPlanId, Limit limit, Sorter sorter) {
		return auditingRepository.findByHql(TrainOutingPlanCloseAuditing.class, "from TrainOutingPlanCloseAuditing i where i.trainPlan.id = ?", new Object[] { trainPlanId });
	}

}
